'''
Created on 15/10/2009

@author: eh01
'''
from ConfigParser import RawConfigParser
from Queue import Queue
from datastore import database
from datastore.resource import Resource, ResourceDict
from optparse import OptionParser
from runtime import rt
from runtime.spaces import Spaces, SpacesContext
from spear.wsdl import WSDL
import os
import sys

class SpearDSUpdate(object):
    '''
    This Class is used by the 'update database' anttask to update the database with a client cert, A2A credentials and WSDLs
    to access SPEAR.
    '''

    def __init__(self, db_path, prop_path):
        self.db_path = db_path
        self.prop_path = prop_path

    def _add_access_token(self, ds, spear_user_username, spear_user_password, spear_user_remote_user, spear_user_access_level, uri_spear, uri_datastore):
        '''
        Saves an access token to the datastore.
        
        Creates a access token resource from the credentials passed in and stores it in the datastore.
        
        Returns: None
        
        Parameters:
        ds -- datastore.database.DataStore: Datastore to save the access token in.
        spear_user_username -- String: SPEAR A2A username or hostid.
        spear_user_password -- String: SPEAR A2A user password.
        spear_user_remote_user -- String: Remote User name.
        spear_user_access_level -- String: SPEAR A2A user access level.
        uri_spear -- datastore.uri.Uri: SPEAR namespace uri.
        uri_datastore -- datastore.uri.Uri: Datastore namespace uri.
        '''
        access_token = Resource()
        access_token.spear_user_access_level = spear_user_access_level
        access_token.spear_user_username = spear_user_username
        access_token.spear_user_password = spear_user_password
        access_token.spear_user_remote_user = spear_user_remote_user
        access_token.set_metadata(uri_datastore.resource.type, uri_spear.type.pvtaccesstoken)
        ds.put([access_token])

    def _add_client_cert(self, ds, client_cert_path, client_cert_password, uri_spear, uri_datastore):
        '''
        Saves a client certificate to the datastore.
        
        Creates a client certificate resource from the data passed in and stores it in the datastore.
        
        Returns: None
        
        Parameters:
        ds -- datastore.database.DataStore: Datastore to save the client cert in.
        client_cert_path -- String: Absoluate path to the client certificate.
        client_cert_password -- String: Password to the certificate.
        uri_spear -- datastore.uri.Uri: SPEAR namespace uri.
        uri_datastore -- datastore.uri.Uri: Datastore namespace uri.
        '''
        content_as_string = open(client_cert_path, 'rb').read()
        client_cert = Resource()
        client_cert.content = content_as_string
        client_cert.set_metadata(uri_datastore.resource.type, uri_spear.type.client_cert)
        client_cert.set_metadata(uri_spear.cert.password, client_cert_password)
        ds.put([client_cert])

    def _add_wsdl(self, wsdl_path, wsdl_name, ds, uri_datastore, uri_spear):
        '''
        Saves a WSDL to the datastore.
        
        Creates a WSDL resource from the data passed in and stores it in the datastore.
        
        Returns: None
        
        Parameters:
        wsdl_path -- String: Absolute path to the folder that contains the WSDL.
        wsdl_name -- String: Name of the WSDL file to add.
        ds -- datastore.database.DataStore: Datastore to save the client cert in.
        uri_datastore -- datastore.uri.Uri: Datastore namespace uri.
        uri_spear -- datastore.uri.Uri: SPEAR namespace uri.
        '''        
        wsdl_file = open(wsdl_path + wsdl_name + '.wsdl', 'rb')
        wsdl_string = wsdl_file.read()
        wsdl_file.close()
        wsdl_file = None
        wsdl = WSDL(wsdl_string)
        rs_wsdl = Resource()
        rs_wsdl.element_dictionary = wsdl.element_dictionary
        rs_wsdl.set_metadata(uri_datastore.resource.type, uri_spear.type.wsdl)
        rs_wsdl.set_metadata(uri_spear.wsdl.name, wsdl_name)
        ds.put([rs_wsdl]) 
        
    def update(self):
        '''
        Updates the datastore with A2A data.
        
        Stores the:
        - client cert
        - a2a user credentials
        - wsdls
        
        Returns: None
        '''
        # initialise spaces with the config files.
        queue = Queue()
        spaces = Spaces()
        spaces_context = SpacesContext(spaces, queue)
        runtime = rt.Runtime()
        runtime.initialise_spaces_with_local_config_files(spaces_context)       
        
        # update the path to the database in the database module.
        database.DATABASE_NAME = self.db_path
        ds = database.DataStore()
        
        # parse the a2a properties file.
        section = 'a2a data'
        cp = RawConfigParser()
        properties_file_path = self.prop_path
        cp.read(properties_file_path)
        client_cert_file_name = cp.get(section, 'clientcertfilename')
        client_cert_password = cp.get(section, 'clientcertpassword')
        spear_user_username = cp.get(section, 'spearuserusername')
        spear_user_password = cp.get(section, 'spearuserpassword')
        spear_user_remote_user = cp.get(section, 'spearuserremoteuser')
        spear_user_access_level = cp.get(section, 'spearuseraccesslevel')
        wsdl_path = cp.get(section, 'wsdlpath')
        
        uri_spear = spaces.uri('spear:')
        uri_datastore = spaces.uri('datastore:')
        
        # update datastore with client cert 
        self._add_client_cert(ds, client_cert_file_name, client_cert_password, uri_spear, uri_datastore)
        # update datastore with access token
        self._add_access_token(ds, spear_user_username, spear_user_password, spear_user_remote_user, spear_user_access_level, uri_spear, uri_datastore)
        # update datastore with SPEAR WSDLs        
        self._add_wsdl(wsdl_path, 'LxSpearEcho', ds, uri_datastore, uri_spear)
        self._add_wsdl(wsdl_path, 'LxSpearDocumentTypes', ds, uri_datastore, uri_spear)
        self._add_wsdl(wsdl_path, 'LxSpearApplicationList', ds, uri_datastore, uri_spear)

if __name__ == '__main__':
    parser = OptionParser(usage=u"%s options." % sys.argv[0])
    
    parser.add_option("-d", "--dbpath",
    dest=u"db_path",
    help=u"Absolute path of the db file.")
    
    parser.add_option("-p", "--proppath",
    dest=u"prop_path",
    help=u"Absolute path of the a2a properties file.")

    (options, args) = parser.parse_args()
    
    # update the db
    spear_ds_update = SpearDSUpdate(options.db_path, options.prop_path)
    spear_ds_update.update()